# coding: utf-8

from __future__ import absolute_import

import unittest
import requests
import rstr

from spapi.auth.credentials import SPAPIConfig
from spapi.client import SPAPIClient
from {{packageName}}.{{apiPackage}}.{{classVarName}} import {{classname}}

import {{packageName}}.{{modelPackage}} as models

class {{#operations}}Test{{classname}}(unittest.TestCase):
    """{{classname}} unit test stubs"""

    def setUp(self):
        # Tests Mock Server
        self.mock_server_endpoint = "http://localhost:3000"
        self.mock_server_endpoint_oauth = "http://localhost:3000/auth/o2/token"
        config = SPAPIConfig(
            client_id="clientId",
            client_secret="clientSecret",
            refresh_token="refreshToken",
            region="NA",
            scope = None
        )
        client = SPAPIClient(config, self.mock_server_endpoint_oauth, self.mock_server_endpoint)
        self.api = {{classname}}(client.api_client)

    def tearDown(self):
        pass

   {{#operation}}
    def test_{{operationId}}(self):
        {{#allParams}}{{#required}}{{paramName}} = {{#isArray}}[self._get_random_value("{{{dataType}}}") for _ in range(1)]{{/isArray}}{{^isArray}}self._get_random_value("{{dataType}}", {{#pattern}}"{{{vendorExtensions.x-regex}}}".replace("*$", "{"+ "{{#minLength}}{{{minLength}}}{{/minLength}}{{^minLength}}0{{/minLength}}{{#maxLength}},{{{maxLength}}}{{/maxLength}}" + "}$"){{/pattern}}{{^pattern}}None{{/pattern}}){{/isArray}}
        {{/required}}{{/allParams}}
        self.instruct_backend_mock(self.to_camel_case("{{operationId}}"), "{{responses.0.code}}")
        response = self.api.{{operationId}}_with_http_info({{#allParams}}{{#required}}{{paramName}}, {{/required}}{{/allParams}})
        {{#returnType}}
        self.assertEqual({{responses.0.code}}, response[1])
        self.assert_valid_response_payload({{responses.0.code}}, response[0])
        {{/returnType}}
        pass

   {{/operation}}
{{/operations}}

    def instruct_backend_mock(self, response: str, code: str) -> None:
        url = f"{self.mock_server_endpoint}/response/{response}/code/{code}"
        ## handle same api operation name exceptions
        if "vendor" in "{{apiPackage}}" and response == "getOrder":
            url += f"?qualifier=Vendor"
        if "fulfillment_inbound" in "{{apiPackage}}" and response == "getShipment":
            url += f"?qualifier=FbaInbound"
        if "seller_wallet" in "{{apiPackage}}" and response == "getAccount":
            url += f"?qualifier=SellerWallet"
        if "seller_wallet" in "{{apiPackage}}" and response == "getTransaction":
            url += f"?qualifier=SellerWallet"
        requests.post(url)

    def _get_random_value(self, data_type, pattern=None):
        if pattern:
            return rstr.xeger(pattern)

        basic_types = {
            'str': "test_string",
            'string': "test_string",
            'int': 123,
            'integer': 123,
            'float': 123.45,
            'bool': True,
            'boolean': True
        }

        return basic_types.get(data_type.lower(), {})

    def assert_valid_response_payload(self, status_code: int, body: any) -> None:
        if status_code != 204:
            self.assertIsNotNone(body)

    def to_camel_case(self, snake_str):
        components = snake_str.split('_')
        return components[0] + ''.join(x.title() for x in components[1:])

if __name__ == '__main__':
    unittest.main()